﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;

namespace MyGame
{
    public class Menu : Microsoft.Xna.Framework.Game
    {
        enum BState
        {
            HOVER,
            UP,
            JUST_RELEASED,
            DOWN
        }

        const int NUMBER_OF_BUTTONS = 4,
            NEWGAME_BUTTON_INDEX = 0,
            CONTINUE_BUTTON_INDEX = 1,
            OPTION_BUTTON_INDEX = 2,
            QUIT_BUTTON_INDEX = 3,

            BUTTON_HEIGHT = 90,
            BUTTON_WIDTH = 258;


        Color background_color;
        Color[] button_color = new Color[NUMBER_OF_BUTTONS];
        Rectangle[] button_rectangle = new Rectangle[NUMBER_OF_BUTTONS];
        BState[] button_state = new BState[NUMBER_OF_BUTTONS];
        Texture2D[] button_texture = new Texture2D[NUMBER_OF_BUTTONS];
        double[] button_timer = new double[NUMBER_OF_BUTTONS];
        //mouse pressed and mouse just pressed
        bool mpressed, prev_mpressed = false;
        //mouse location in window
        int mx, my;
        double frame_time;

        // for simulating button clicks with keyboard
        KeyboardState keyboard_state, last_keyboard_state;


        Texture2D background;
        Texture2D menu;

        //Methods:
        public void Init()
        {
            int x = GameOption.ScreenWidth / 2 - BUTTON_WIDTH / 2;
            int y =520 -
               NUMBER_OF_BUTTONS / 2 * BUTTON_HEIGHT -
               (NUMBER_OF_BUTTONS % 2) * BUTTON_HEIGHT / 2;


            for (int i = 0; i < NUMBER_OF_BUTTONS;i++ )
            {
                button_state[i] = BState.UP;
                button_color[i] = Color.White;
                button_timer[i] = 0.0;
                button_rectangle[i] = new Rectangle(x, y, BUTTON_WIDTH, BUTTON_HEIGHT);
                y += BUTTON_HEIGHT;
                
            }

            IsMouseVisible = true;
        }

        public void LoadMenu(ContentManager content)
        {
            button_texture[NEWGAME_BUTTON_INDEX] = content.Load<Texture2D>(@"images\new");
            button_texture[CONTINUE_BUTTON_INDEX] = content.Load<Texture2D>(@"images\continue");
            button_texture[OPTION_BUTTON_INDEX] = content.Load<Texture2D>(@"images\option");
            button_texture[QUIT_BUTTON_INDEX] = content.Load<Texture2D>(@"images\quit");
            menu = content.Load<Texture2D>(@"images\menu");
            background = content.Load<Texture2D>(@"images\intro_logo");
            

        }

        public  void DrawButton(SpriteBatch spriteBatch, GameTime gameTime)
        {
            spriteBatch.Begin();
            spriteBatch.Draw(background, new Vector2(0, 0), Color.White);
            //spriteBatch.Draw(menu, new Vector2(GameOption.ScreenWidth/2, GameOption.ScreenHeight/2), Color.White);
            for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
            {
                //spriteBatch.Draw(background, new Vector2(0, 0), button_color[i]);
                spriteBatch.Draw(button_texture[i], button_rectangle[i], button_color[i]);
            }
            
            spriteBatch.End();
        }

        //Action on button
        //Các thủ tục xử lí mình cho vô đây
        public void TakeActionOnButton(int i)
        {
               switch(i)
               {
                   case NEWGAME_BUTTON_INDEX:
                       break;
                   case CONTINUE_BUTTON_INDEX:
                       break;
                   case OPTION_BUTTON_INDEX:
                       break;
                   case QUIT_BUTTON_INDEX:
                       this.Exit();
                       break;
                   default:
                       break;
               }
        }
        public void HandleKeyboard()
        {
            last_keyboard_state = keyboard_state;
            keyboard_state = Keyboard.GetState();
            Keys[] keymap = (Keys[])keyboard_state.GetPressedKeys();
            foreach (Keys k in keymap)
            {
                char key = k.ToString()[0];
                switch(key)
                {
                    case 'n':
                    case 'N':
                        TakeActionOnButton(NEWGAME_BUTTON_INDEX);
                        button_color[NEWGAME_BUTTON_INDEX] = Color.Red;
                        button_timer[NEWGAME_BUTTON_INDEX] = 0.25;
                        break;

                    case 'c':
                    case 'C':
                        TakeActionOnButton(CONTINUE_BUTTON_INDEX);
                        button_color[CONTINUE_BUTTON_INDEX]= Color.Red;
                        button_timer[CONTINUE_BUTTON_INDEX] = 0.25;
                        break;

                    case 'o':
                    case 'O':
                        TakeActionOnButton(OPTION_BUTTON_INDEX);
                        button_color[OPTION_BUTTON_INDEX] = Color.Red;
                        button_timer[OPTION_BUTTON_INDEX] = 0.25;
                        break;

                    case 'q':
                    case 'Q':
                        TakeActionOnButton(QUIT_BUTTON_INDEX);
                        button_color[QUIT_BUTTON_INDEX] = Color.Red;
                        button_timer[QUIT_BUTTON_INDEX] = 0.25;
                        break;


                }
            }

        }

        // wrapper for hit_image_alpha taking Rectangle and Texture
        Boolean hit_image_alpha(Rectangle rect, Texture2D tex, int x, int y)
        {
            return hit_image_alpha(0, 0, tex, tex.Width * (x - rect.X) /
                rect.Width, tex.Height * (y - rect.Y) / rect.Height);
        }

        // wraps hit_image then determines if hit a transparent part of image
        Boolean hit_image_alpha(float tx, float ty, Texture2D tex, int x, int y)
        {
            if (hit_image(tx, ty, tex, x, y))
            {
                uint[] data = new uint[tex.Width * tex.Height];
                tex.GetData<uint>(data);
                if ((x - (int)tx) + (y - (int)ty) *
                    tex.Width < tex.Width * tex.Height)
                {
                    return ((data[
                        (x - (int)tx) + (y - (int)ty) * tex.Width
                        ] &
                                0xFF000000) >> 24) > 20;
                }
            }
            return false;
        }

        // determine if x,y is within rectangle formed by texture located at tx,ty
        Boolean hit_image(float tx, float ty, Texture2D tex, int x, int y)
        {
            return (x >= tx &&
                x <= tx + tex.Width &&
                y >= ty &&
                y <= ty + tex.Height);
        }


        public void UpdateButton()
        {

            for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
            {

                if (hit_image_alpha(
                    button_rectangle[i], button_texture[i], mx, my))
                {
                    button_timer[i] = 0.0;
                    if (mpressed)
                    {
                        // mouse is currently down
                        button_state[i] = BState.DOWN;
                        button_color[i] = Color.Blue;
                    }
                    else if (!mpressed && prev_mpressed)
                    {
                        // mouse was just released
                        if (button_state[i] == BState.DOWN)
                        {
                            // button i was just down
                            button_state[i] = BState.JUST_RELEASED;
                        }
                    }
                    else
                    {
                        button_state[i] = BState.HOVER;
                        button_color[i] = Color.LightBlue;
                    }
                }
                else
                {
                    button_state[i] = BState.UP;
                    if (button_timer[i] > 0)
                    {
                        button_timer[i] = button_timer[i] - frame_time;
                    }
                    else
                    {
                        button_color[i] = Color.White;
                    }
                }

                if (button_state[i] == BState.JUST_RELEASED)
                {
                    TakeActionOnButton(i);
                }
            }
        }


        public void Update(GameTime gameTime)
        {
            HandleKeyboard();

            // update mouse variables
            MouseState mouse_state = Mouse.GetState();
            mx = mouse_state.X;
            my = mouse_state.Y;
            prev_mpressed = mpressed;
            mpressed = mouse_state.LeftButton == ButtonState.Pressed;

            UpdateButton();
        }

    }
}
                                                                                       